/**
 * @file lv_port_indev_templ.c
 *
 */

/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_indev.h"
#include "../../lvgl.h"
#include "../../../user/Driver/Display/mcu_display/mcu_display_driver.h"//自己的屏幕驱动
#include "../../../User/Driver/Display/rgb_display/rgb_display_driver.h"

#include "../../../User/Driver/Display/mcu_display/res_xpt2046.h"//自己的触碰驱动
#include "../../../User/Driver/Display/rgb_display/cap_gt9xx.h"


/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

static void touchpad_init(void);
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);

static void mouse_init(void);
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool mouse_is_pressed(void);
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);

static void keypad_init(void);
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);

static void encoder_init(void);
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_handler(void);

static void button_init(void);
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static int8_t button_get_pressed_id(void);
static bool button_is_pressed(uint8_t id);

/**********************
 *  STATIC VARIABLES
 **********************/
lv_indev_t * indev_touchpad;
lv_indev_t * indev_mouse;
lv_indev_t * indev_keypad;
lv_indev_t * indev_encoder;
lv_indev_t * indev_button;

static int32_t encoder_diff;
static lv_indev_state_t encoder_state;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_indev_init(void)
{
    /**
     * 在这里你会找到LittelvGL所支持的输入设备的示例实现：
     *  - Touchpad
     *  - Mouse (支持光标)
     *  - Keypad (仅在使用密钥时支持图形用户界面（GUI）使用)
     *  - Encoder (仅支持图形用户界面（GUI）与以下操作配合使用：左移、右移、推送)
     *  - Button (用于点击屏幕上点位的外部按钮)
     *
     *  `..._read()`函数只是示例。
     *  你应该根据你的硬件来塑造它们。
     */

    static lv_indev_drv_t indev_drv;

    /*------------------
     * Touchpad 触控板
     * -----------------*/

    /*如果您有触摸板，请初始化它*/
    touchpad_init();

    /*注册触摸板输入设备*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv);
#if 0
    /*------------------
     * Mouse 鼠标
     * -----------------*/

    /*如果您有鼠标，请初始化它*/
    mouse_init();

    /*注册一个鼠标输入设备*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = mouse_read;
    indev_mouse = lv_indev_drv_register(&indev_drv);

    /*设置光标。为简单起见，现在设置一个HOME符号。*/
    lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
    lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
    lv_indev_set_cursor(indev_mouse, mouse_cursor);

    /*------------------
     * Keypad 键盘
     * -----------------*/

    /*如果有的话，请初始化你的小键盘或键盘*/
    keypad_init();

    /*注册一个键盘输入设备*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv.read_cb = keypad_read;
    indev_keypad = lv_indev_drv_register(&indev_drv);

    /*之后，你应该使用`lv_group_t * group = lv_group_create()`来创建一个或多个组，
     *使用`lv_group_add_obj(组, 对象)`向组中添加对象
     *并将此输入设备分配到组中以在其中导航：
     *lv_indev_set_group(indev_keypad, group);*/

    /*------------------
     * Encoder 编码器
     * -----------------*/

    /*如果有的话，请初始化你的编码器*/
    encoder_init();

    /*注册编码器输入设备*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_ENCODER;
    indev_drv.read_cb = encoder_read;
    indev_encoder = lv_indev_drv_register(&indev_drv);

    /*之后，你应该使用`lv_group_t * group = lv_group_create()`来创建一个或多个组，
     *使用`lv_group_add_obj(组, 对象)`向组中添加对象
     *并将此输入设备分配到组中以在其中导航：
     *`lv_indev_set_group(indev_encoder, group);`*/

    /*------------------
     * Button 按钮
     * -----------------*/

    /*如果有的话，请初始化你的按钮*/
    button_init();

    /*注册一个按钮输入设备*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_BUTTON;
    indev_drv.read_cb = button_read;
    indev_button = lv_indev_drv_register(&indev_drv);

    /*将按钮分配到屏幕上的各个点*/
    static const lv_point_t btn_points[2] = {
        {10, 10},   /*Button 0 -> x:10; y:10*/
        {40, 100},  /*Button 1 -> x:40; y:100*/
    };
    lv_indev_set_button_points(indev_button, btn_points);
#endif
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*------------------
 * Touchpad 触控板
 * -----------------*/

/*初始化你的触控板*/
static void touchpad_init(void)
{
#if 0
    WHT_XPT2046_Init();
#else
    WHT_GT9xx_Driver.WHT_Init();
#endif
}

/*将由库调用以读取触摸板*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*保存按下的坐标和状态*/
    if(touchpad_is_pressed())
    {
        touchpad_get_xy(&last_x, &last_y);
        data->state = LV_INDEV_STATE_PR;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }
    /*设置最后按下的坐标*/
    data->point.x = last_x;
    data->point.y = last_y;
}

/*如果触摸板被按下，则返回true*/
static bool touchpad_is_pressed(void)
{
    /*添加自己的代码 0未按下 1按下*/
#if 0
    WHT_XPT2046_Touch_Even_Handler(Display_Mode5);
    return WHT_XPT2046_Pos.State == 0 ? false : true;
#else
    return WHT_GT9xx_Driver.WHT_Touch_Pos[0]->State == 0 ? false : true;
#endif
}

/*如果触摸板被按下，获取x和y坐标*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
    /*添加触摸坐标*/
#if 0
    if (WHT_XPT2046_Pos.State != false)
    {
        (*x) = WHT_XPT2046_Pos.New_X;
        (*y) = WHT_XPT2046_Pos.New_Y;
        return
    }
#else
    for (size_t i = 0; i < GT9xx_Max_Touch_Count; i++)
    {
        if (WHT_GT9xx_Driver.WHT_Touch_Pos[i]->State != false)
        {
            (*x) = WHT_GT9xx_Driver.WHT_Touch_Pos[i]->New_X;
            (*y) = WHT_GT9xx_Driver.WHT_Touch_Pos[i]->New_Y;
            return;
        }
    }
#endif
    (*x) = 0;
    (*y) = 0;
}

/*------------------
 * Mouse 鼠标
 * -----------------*/

/*初始化你的鼠标*/
static void mouse_init(void)
{
    /*Your code comes here*/
}

/*将由库调用以读取鼠标*/
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    /*获取当前的x和y坐标*/
    mouse_get_xy(&data->point.x, &data->point.y);

    /*获取鼠标按钮是按下还是松开的状态*/
    if(mouse_is_pressed()) {
        data->state = LV_INDEV_STATE_PR;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }
}

/*如果鼠标按钮被按下，则返回true*/
static bool mouse_is_pressed(void)
{
    /*Your code comes here*/

    return false;
}

/*如果鼠标被按下，获取x和y坐标*/
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
{
    /*Your code comes here*/

    (*x) = 0;
    (*y) = 0;
}

/*------------------
 * Keypad 键盘
 * -----------------*/

/*初始化你的键盘*/
static void keypad_init(void)
{
    /*Your code comes here*/
}

/*将由库调用以读取鼠标*/
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static uint32_t last_key = 0;

    /*获取当前的x和y坐标*/
    mouse_get_xy(&data->point.x, &data->point.y);

    /*获取某个按键是否被按下，并保存被按下的按键*/
    uint32_t act_key = keypad_get_key();
    if(act_key != 0) {
        data->state = LV_INDEV_STATE_PR;

        /*根据您的按键定义，将这些按键转换为LVGL控制字符*/
        switch(act_key) {
            case 1:
                act_key = LV_KEY_NEXT;
                break;
            case 2:
                act_key = LV_KEY_PREV;
                break;
            case 3:
                act_key = LV_KEY_LEFT;
                break;
            case 4:
                act_key = LV_KEY_RIGHT;
                break;
            case 5:
                act_key = LV_KEY_ENTER;
                break;
        }

        last_key = act_key;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }

    data->key = last_key;
}

/*获取当前正在按下的键。如果没有按键被按下，则返回0*/
static uint32_t keypad_get_key(void)
{
    /*Your code comes here*/

    return 0;
}

/*------------------
 * Encoder 编码器
 * -----------------*/

/*初始化你的编码器*/
static void encoder_init(void)
{
    /*Your code comes here*/
}

/*将由库调用以读取编码器*/
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{

    data->enc_diff = encoder_diff;
    data->state = encoder_state;
}

/*在中断中调用此函数以处理编码器事件（转动、按压）*/
static void encoder_handler(void)
{
    /*Your code comes here*/

    encoder_diff += 0;
    encoder_state = LV_INDEV_STATE_REL;
}

/*------------------
 * Button 按钮
 * -----------------*/

/*初始化你的按钮*/
static void button_init(void)
{
    /*Your code comes here*/
}

/*将由库调用以读取按钮*/
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{

    static uint8_t last_btn = 0;

    /*获取按下的按钮的ID*/
    int8_t btn_act = button_get_pressed_id();

    if(btn_act >= 0) {
        data->state = LV_INDEV_STATE_PR;
        last_btn = btn_act;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }

    /*保存最后按下的按钮的ID*/
    data->btn_id = last_btn;
}

/*获取所按按钮的ID（0、1、2……）*/
static int8_t button_get_pressed_id(void)
{
    uint8_t i;

    /*检查按钮，看看哪个正在被按下（假设有2个按钮）*/
    for(i = 0; i < 2; i++) {
        /*返回按下的按钮的ID*/
        if(button_is_pressed(i)) {
            return i;
        }
    }

    /*未按下任何按钮*/
    return -1;
}

/*测试`id`按钮是否被按下*/
static bool button_is_pressed(uint8_t id)
{

    /*Your code comes here*/

    return false;
}

#else /*Enable this file at the top*/

/*这个虚拟的类型定义纯粹是为了消除-Wpedantic警告。*/
typedef int keep_pedantic_happy;
#endif
